package thread.ch04;

import java.util.HashSet;
import java.util.Set;

import thread.annotation.GuardBy;
import thread.annotation.ThreadSafe;

/**
 * 通过限制和锁协同确保一个类的线程安全性，即使它的组件状态并不是线程安全的。
 * <p />
 * 非线程安全的HashSet管理者PersonSet的状态。不过由于mySet是私有的，不会逸出，因此HashSet被限制在PersonSet中。
 * <p />
 * 唯一可以访问mySet的代码路径是addPerson与containsPerson，执行它们都要获得PersonSet的锁。
 * <p />
 * PersonSet的内部锁保护了它所有的状态，确保了PersonSet是线程安全的。
 * <p />
 * 本例中未对Person的线程安全性作任何假设。但如果它是可变的，那么访问从PersonSet中获得的Person时，还需要额外的同步。
 * <p />
 * 为了安全地使用Person对象，最可靠的方法是让Person自身是线程安全的：对Person对象加锁并不十分可靠，因为它还需要所有的用户都遵循协议：
 * 访问Person前先获得正确的锁。
 * 
 * @author Edgar Zhang
 * 
 */
@ThreadSafe
public class PersonSet {

	@GuardBy("this")
	private final Set<Person> mySet = new HashSet<Person>();

	public synchronized void addPerson(Person p) {
		mySet.add(p);
	}

	public synchronized boolean containsPerson(Person p) {
		return mySet.contains(p);
	}
}
